﻿using System.Collections.Generic;
using System.Runtime.Serialization.Formatters;

public class LogicStateMachine:BaseComponent
{
    private readonly Actor m_actor;
    private readonly LogicStateBase m_cur_state = null;
    private LogicStateBase m_last_state;
    private LogicStateType m_last_state_type = LogicStateType.Logic_State_Stand;
    private readonly Dictionary<int, LogicStateBase> m_state_list = new Dictionary<int, LogicStateBase>();

    public LogicStateMachine(Actor actor)
    {
        m_actor = actor;
        addState(LogicStateType.Logic_State_Stand);
        addState(LogicStateType.Logic_State_Walk);
    }

    public Actor Actor
    {
        get { return m_actor; }
    }

    protected override void OnUpdate(float deltaTime)
    {
        if (m_cur_state != null)
        {
            m_cur_state.Update(deltaTime);
        }
    }

    protected override void OnLateUpdate(float deltaTime)
    {
        if (m_cur_state != null)
        {
            m_cur_state.LateUpdate(deltaTime);
        }
    }

    private void addState(LogicStateType state_type)
    {
        if (!m_state_list.ContainsKey((int) state_type))
            m_state_list[(int) state_type] = createLogicState(state_type);
    }

    /// <summary>
    ///     状态机切换状态.
    /// </summary>
    /// <param name="state_type">当前状态</param>
    /// <returns></returns>
    public LogicStateBase gotoState(LogicStateType state_type, object param = null)
    {
        //本地转换状态
        if (m_cur_state == null)
        {
            {
#if USE_LOGWRAPPER
                LogWrapper.LogError("[LogicStateMachine][gotoState] m_cur_state == NULL");
#endif
            }
            return m_cur_state;
        }

        if (state_type == m_cur_state.GetState())
        {
            // 站立闲置动作.
            if (m_cur_state.GetState() == LogicStateType.Logic_State_Stand)
            {
                m_cur_state.EnterState(param);
            }

            m_cur_state.ReEnterState();
            return m_cur_state;
        }

        // 切换状态
        m_cur_state.LeaveState();

        m_last_state_type = m_cur_state.GetState();
        m_last_state = m_cur_state;

        return m_cur_state;
    }


    public LogicStateBase getCurState()
    {
        return m_cur_state;
    }


    public LogicStateType getLastStateType()
    {
        return m_last_state_type;
    }

    public bool isStateVaild(LogicStateType state)
    {
        return state > LogicStateType.Logic_State_Null && state < LogicStateType.Logic_State_end;
    }

    private LogicStateBase createLogicState(LogicStateType state_type)
    {
        switch (state_type)
        {
            case LogicStateType.Logic_State_Stand:
            {
                return new LogicStateStand(this);
            }
            case LogicStateType.Logic_State_Walk:
            {
                return new LogicStateWalk(this);
            }
        }

        return null;
    }

    public void Release()
    {
        if (m_cur_state != null)
            m_cur_state.Release();
    }
}